#include "token.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAX_TOKEN_SIZE 1024
#define SECRET_KEY "lunisolar string token key"

int getToken(int userId, char *buf, size_t bufSize)
{
    if (!buf || bufSize == 0) {
        fprintf(stderr, "Invalid buffer or buffer size\n");
        return 1;
    }

    char id[20];
    snprintf(id, sizeof(id), "%d", userId);
    printf("id:%s\n", id);
    char *jwt = NULL;
    size_t jwt_length = 0;
    struct l8w8jwt_encoding_params params;
    l8w8jwt_encoding_params_init(&params);

    params.alg = L8W8JWT_ALG_HS512;
    params.sub = id;
    params.iss = "lunisolar";
    params.aud = "user";
    params.exp = time(NULL) + 3600;
    params.iat = time(NULL);

    params.secret_key = (unsigned char *)SECRET_KEY;
    params.secret_key_length = strlen(SECRET_KEY);
    params.out = &jwt;
    params.out_length = &jwt_length;

    if (l8w8jwt_encode(&params) != L8W8JWT_SUCCESS) {
        fprintf(stderr, "Failed to encode token\n");
        return 1;
    }

    if (jwt_length >= bufSize) {
        fprintf(stderr, "Token is too large for the buffer\n");
        l8w8jwt_free(jwt);
        return 1;
    }

    strncpy(buf, jwt, bufSize - 1);
    buf[bufSize - 1] = '\0';
    l8w8jwt_free(jwt);

    return 0;
}

int getUserId(const char *token)
{
    if (!token) {
        fprintf(stderr, "Token is NULL\n");
        return -1;
    }

    struct l8w8jwt_decoding_params params;
    l8w8jwt_decoding_params_init(&params);

    params.alg = L8W8JWT_ALG_HS512;
    params.jwt = (char *)token;
    params.jwt_length = strlen(token);
    params.verification_key = (unsigned char *)SECRET_KEY;
    params.verification_key_length = strlen(SECRET_KEY);

    struct l8w8jwt_claim *claims = NULL;
    size_t claim_count = 0;
    enum l8w8jwt_validation_result validation_result;

    if (l8w8jwt_decode(&params, &validation_result, &claims, &claim_count) != L8W8JWT_SUCCESS || validation_result != L8W8JWT_VALID) {
        fprintf(stderr, "Failed to decode token or token is invalid\n");
        return -1;
    }

    int userId = -1;
    for (size_t i = 0; i < claim_count; i++) {
        if (strcmp(claims[i].key, "sub") == 0) {
            userId = atoi(claims[i].value);
            break;
        }
    }

    l8w8jwt_free_claims(claims, claim_count);
    return userId;
}
//test
// int main()
// {
//     int userId = 12345;
//     char token[MAX_TOKEN_SIZE] = { 0 };

//     if (getToken(userId, token, sizeof(token)) != 0) {
//         fprintf(stderr, "Failed to generate token\n");
//         return 1;
//     }

//     printf("Generated Token: %s\n", token);

//     int parsedUserId = getUserId(token);
//     if (parsedUserId == userId) {
//         printf("Test passed: User ID %d matches\n", userId);
//     } else {
//         fprintf(stderr, "Test failed: User ID %d does not match parsed User ID %d\n", userId, parsedUserId);
//         return 1;
//     }

//     return 0;
// }
